package com.cloud.log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Arrays;

@Aspect
public class WebLogAspect {

    private static Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class);

    ThreadLocal<Long> startTime = new ThreadLocal<>();


//    @Pointcut(value="execution(* com.cloud..*.*(..)) && @annotation(com.cloud.log.AutoLog)")
    @Pointcut(value="execution(* com..*.controller..*.*(..))")
    public void pointCut(){
    }


    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){

        startTime.set(System.currentTimeMillis());
        //接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpSession session = request.getSession();
        // 记录下请求内容
        LOGGER.info("URL : " + request.getRequestURL().toString());
        LOGGER.info("HTTP_METHOD : " + request.getMethod());
        LOGGER.info("IP : " + getIpAddr(request));
        LOGGER.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        LOGGER.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(returning = "ret", pointcut = "pointCut()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求，返回内容
        LOGGER.info("RESPONSE : " + ret);
        LOGGER.info("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));
        startTime.remove();//用完之后记得清除，不然可能导致内存泄露;
    }



//    @Around("pointCut()")
//    public Object doMethod(ProceedingJoinPoint joinPoint) throws Throwable {
//        if (joinPoint == null) {
//            return null;
//        }
//
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        String ip = getIpAddr(request);
//
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        Method method = signature.getMethod();
//        AutoLog autoLOGGER = method.getAnnotation(AutoLog.class);
//        Object[] params = joinPoint.getArgs();//获取请求参数
//
//        String operateType = autoLOGGER.operateUser();
//        String operType = autoLOGGER.operateType();//操作类型
//
//        JSONObject message = new JSONObject();
//        message.put("ip",ip);
//        message.put("operateType",operateType);
//        message.put("operType",operType);
//        message.put("method",method.getDeclaringClass());
//        message.put("params",params);
////        kafkaTemplate.send("LOGGER",message.toJSONString());
//
//
//        //###################上面代码为方法执行前#####################
//        Object result  = joinPoint.proceed();//执行方法，获取返回参数
//        //###################下面代码为方法执行后#####################
//        System.out.println("返回参数为:" + result);
//        message = new JSONObject();
//        message.put("ip",ip);
//        message.put("operateType",operateType);
//        message.put("operType",operType);
//        message.put("method",method.getDeclaringClass());
//        message.put("params",params);
//
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        message.put("response_time", LocalDateTime.now().format(dateTimeFormatter));
//        message.put("response_content", result);
////        kafkaTemplate.send("LOGGER",message.toJSONString());
//
//        return result;
//    }

    public String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0
                || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0
                || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0
                || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }

        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
            // = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        //或者这样也行,对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        //return ipAddress!=null&&!"".equals(ipAddress)?ipAddress.split(",")[0]:null;
        return ipAddress;
    }
}
